/*
 * Monkey-Moore - A simple and powerful relative search tool
 * Copyright (C) 2007 Ricardo J. Ricken (Darkl0rd)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#ifndef MONKEY_MOORE_HPP
#define MONKEY_MOORE_HPP

#include <wx/wxprec.h>

#ifdef __BORLANDC__
#pragma hdrstop
#endif

#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif

#include "object_pred.hpp"

#include <wx/wxchar.h>
#include <map>
#include <string>
#include <utility>
#include <vector>

typedef unsigned char u8;
typedef std::map <wxChar, u8> equivalency_type;
typedef std::pair <long, equivalency_type> relative_type;

/**
* Manages and performs relative searchs.
*/
class MonkeyMoore
{
public:
   MonkeyMoore (const wxString &key, const wxChar &wildcard = 0, const wxString &pattern = wxT(""));
   MonkeyMoore (const std::vector <short> &vals);
   ~MonkeyMoore ();

   std::vector <relative_type> search (const u8 *data, long len);

private:
   void preprocess ();
   void init (const wxChar *kw, const int ksz, const wxChar *cp);
   std::vector <relative_type> monkey_moore (const u8 *data, long len);
   std::vector <relative_type> monkey_moore_wc (const u8 *data, long len);

   template <class T> inline void calc_reltable (const T *src, int *tbl, int size) const;
   void calc_reltable_cp (const wxChar *src, int *tbl, int size);

   // general attributes

   wxChar *key;        // search key
   long klen;          // key length
   int *key_tbl;       // key's relative table
   char skip[512];     // jump table

   enum { none, simple_relative, wildcard_relative, value_scan } type;

   // wildcard search attributes

   wxChar *mdkey;      // modified key (ie: MonkeyMoore -> *onkey*oore)
   u8 *cards;          // wildcards jump table
   bool *wc_pos;       // wildcard map

   bool case_change;   // indicates change in key's capitalization
   bool lower;         // there are more lower characters then upper?
   int n_wildcards;    // how many wildcards in key

   const wxChar card;  // wildcard character (0 means no wildcard)

   // special attributes

   bool custom_charpattern;
   wxChar *char_pattern;
   int cplen;

   std::map <wxChar, int> cp_pos;
};

#endif //~MONKEY_MOORE_HPP
